2020-2021 Sunseeker Telemetry and Lighting System
sdhs_ex1_8msps_sampling.c
Go to the documentation of this file.
1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
32 //******************************************************************************
33 // sdhs_ex1_8msps_sampling.c - SDHS sampling at 8MSPS and DTC transfer results to RAM
34 //
35 // Description: Configure the SDHS for stand-alone use (register mode) at 8MSPS.
36 // Use the DTC to transfer the results to an array in RAM.
37 //
38 // MSP430FR6047
39 // ---------------
40 // /|\| |
41 // | | |
42 // --|RST |
43 // | P1.0|---> LED
44 // | |-USSXTIN
45 // | |-USSXTOUT
46 // | CH0_IN|<--- input signal
47 //
48 // Wallace Tran
49 // Texas Instruments Inc.
50 // June 2017
51 //******************************************************************************
52 #include "driverlib.h"
53 
54 #if defined(__TI_COMPILER_VERSION__)
55 #pragma DATA_SECTION(results, ".leaRAM")
56 #pragma RETAIN(results)
57 uint16_t results[1024] = {0};
58 #elif defined(__IAR_SYSTEMS_ICC__)
59 #pragma location = 0x2C00
60 __no_init uint16_t results[1024];
61 #pragma required = results
62 #elif defined(__GNUC__)
63 uint16_t results[1024] __attribute__ ((section(".leaRAM"), used));
64 #else
65 #error Compiler not supported!
66 #endif
67 
68 void main(void)
69 {
70  // Stop WDT
71  WDT_A_hold(WDT_A_BASE);
72 
73  // Configure P1.0 as output for LED
74  GPIO_setAsPeripheralModuleFunctionOutputPin(
75  GPIO_PORT_P1,
76  GPIO_PIN0,
77  GPIO_PRIMARY_MODULE_FUNCTION
78  );
79 
80  // Disable the GPIO power-on default high-impedance mode to activate
81  // previously configured port settings
82  PMM_unlockLPM5();
83 
84  // Configure one FRAM waitstate as required by the device datasheet for MCLK
85  FRAMCtl_A_configureWaitStateControl(FRAMCTL_A_ACCESS_TIME_CYCLES_1);
86 
87  /* ---Begin Clock System Setup--- */
88  // Per Device Errata set divider to 4 before changing frequency to
89  // prevent out of spec operation from overshoot transient
90  CS_initClockSignal(CS_ACLK, CS_VLOCLK_SELECT, CS_CLOCK_DIVIDER_4);
91  CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4);
92  CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4);
93  // Set DCO to 16MHz
94  CS_setDCOFreq(CS_DCORSEL_1, CS_DCOFSEL_4);
95  // Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
96  __delay_cycles(60);
97  // Set all dividers to 1 for 16MHz operation
98  // MCLK = SMCLK = 16MHz
99  CS_initClockSignal(CS_ACLK, CS_VLOCLK_SELECT, CS_CLOCK_DIVIDER_1);
100  CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
101  CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
102  /* ---End Clock System Setup--- */
103 
104  /* ---Begin Setup SAPH Bias Register Controlled--- */
105  SAPH_unlock(SAPH_BASE);
106  SAPH_configPHYBiasParam saphParam = {0};
107  saphParam.enableChargePump = SAPH_PHY_MULTIPLEXER_CHARGEPUMP_ENABLE;
108  saphParam.biasSwitchASQ = SAPH_PHY_BIAS_SWITCH_CONTROLLED_BY_REGISTER;
109  saphParam.biasPGA = SAPH_PHY_PGA_BIAS_NOMINAL_VALUE;
110  saphParam.biasExcitation = SAPH_PHY_EXCITATION_BIAS_NOMINAL_VALUE;
111  SAPH_configurePHYBias(SAPH_BASE, &saphParam);
112  SAPH_configurePHYMultiplexer(SAPH_BASE, SAPH_PHY_DUMMYLOAD_DISABLE,
113  SAPH_PHY_SOURCE_CONTROLLED_BY_REGISTER,
114  SAPH_PHY_INPUT_CHANNEL_0);
115  SAPH_lock(SAPH_BASE);
116  /* ---End Setup SAPH Bias Register Controlled--- */
117 
118  /* ---Begin initialize the HSPLL and wait for it to lock--- */
119  // Configure USSXT Oscillator
120  HSPLL_xtalInitParam xtalParam;
121  xtalParam.oscillatorType = HSPLL_XTAL_OSCTYPE_XTAL;
122  xtalParam.oscillatorEnable = HSPLL_XTAL_ENABLE;
123  xtalParam.xtlOutput = HSPLL_XTAL_OUTPUT_ENABLE;
124  HSPLL_xtalInit(HSPLL_BASE, &xtalParam);
125 
126  // Check if oscillator is stable
127  while(HSPLL_getOscillatorStatus(HSPLL_BASE) == HSPLL_OSCILLATOR_NOT_STABILIZED);
128 
129  // Set up timer to wait in LPM for crystal stabilization time = 4096 clocks for crystal resonator.
130  // For 8MHz XTAL, 4096 clocks = 512us. Using VLO = 9.4kHz, wait 5 timer clock cycles = 532us.
131  Timer_A_initUpModeParam timerParam = {0};
132  timerParam.timerPeriod = 5;
133  timerParam.captureCompareInterruptEnable_CCR0_CCIE =
134  TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
135  // Timer sourced from ACLK (VLO)
136  timerParam.clockSource = TIMER_A_CLOCKSOURCE_ACLK;
137  // Clear timer
138  timerParam.timerClear = TIMER_A_DO_CLEAR;
139  timerParam.startTimer = true;
140  Timer_A_initUpMode(TA4_BASE, &timerParam);
141 
142  // Enter LPM3 w/interrupts enabled
143  __bis_SR_register(LPM3_bits | GIE);
144 
145  // For debugger
146  __no_operation();
147 
148  // Init PLL
149  // Use the PLL multiplier setting to get 80MHz output from our 8MHz input
150  // Equation: PLL output clock frequency x 2 = input clock frequency x (hspllParam.multiplier+1)
151  // Input clock frequency = 8MHz
152  // Desired PLL output clock frequency = 80MHz
153  // hspllParam.multipler = 19
154  HSPLL_initParam hspllParam;
155  hspllParam.multiplier = PLLM_19_H;
156  hspllParam.frequency = HSPLL_GREATER_THAN_6MHZ;
157  HSPLL_init(HSPLL_BASE, &hspllParam);
158 
159  // Power up the UUPS to start the PLL
160  UUPS_turnOnPower(UUPS_BASE, UUPS_POWERUP_TRIGGER_SOURCE_USSPWRUP);
161 
162  // Wait for UUPS to power up
163  while(UUPS_getPowerModeStatus(UUPS_BASE) != UUPS_POWERMODE_READY);
164 
165  // Wait for PLL to lock
166  while(HSPLL_isLocked(HSPLL_BASE) == HSPLL_UNLOCKED);
167 
168  /* ---End initialize the HSPLL and wait for it to lock--- */
169 
170  /* ---Begin setup the SDHS with register mode--- */
171  SDHS_initParam sdhsParam = {0};
172  // Software trigger
173  sdhsParam.triggerSourceSelect = SDHS_REGISTER_CONTROL_MODE;
174  // Automatic sample start after settling delay
175  sdhsParam.autoSampleStart = SDHS_AUTO_SAMPLE_START_DISABLED;
176  sdhsParam.dataAlignment = SDHS_DATA_FORMAT_OFFSET_BINARY;
177  sdhsParam.dataFormat = SDHS_DATA_ALIGNED_LEFT;
178  // OSR = 10 (80MHz/10 = 8MSPS). CS must be set MCLK >= 8 MHz.
179  sdhsParam.oversamplingRate = SDHS_OVERSAMPLING_RATE_10;
180  SDHS_init(SDHS_BASE, &sdhsParam);
181  // 256 samples
182  SDHS_setTotalSampleSize(SDHS_BASE, 256);
183  // PGA Gain 0.1 dB
184  SDHS_setPGAGain(SDHS_BASE, 0x1A);
185  // 80MHz PLL output frequency
186  SDHS_setModularOptimization(SDHS_BASE, SDHS_OPTIMIZE_PLL_OUTPUT_FREQUENCY_77_80MHz);
187  // DTC transfer data to start of LEA RAM
188  SDHS_setDTCDestinationAddress(SDHS_BASE, 0);
189  // Enable acquisition done interrupt (after 256 samples transferred)
190  SDHS_enableInterrupt(SDHS_BASE, SDHS_ACQUISITION_DONE_INTERRUPT);
191  // Enable trigger
192  SDHS_enableTrigger(SDHS_BASE);
193  // Turn on SD and start conversion
194  SDHS_enable(SDHS_BASE);
195  SDHS_startConversion(SDHS_BASE);
196  // Delay for PGA worst case 40us settling time
197  __delay_cycles(320);
198  /* ---End setup the SDHS with register mode--- */
199 
200  /* ---Begin configure TA2.1 for 1/sec to trigger the pulse generation and toggle LED--- */
201  Timer_A_initUpModeParam timerParam2 = {0};
202  timerParam2.timerPeriod = 9400;
203  TA2CCR1 = 4700;
204  TA2CCTL1 = OUTMOD_7 | CCIE; // Enable output signal to trigger PPG, enable interrupt
205  // Timer sourced from ACLK (VLO)
206  timerParam2.clockSource = TIMER_A_CLOCKSOURCE_ACLK;
207  // Clear timer
208  timerParam2.timerClear = TIMER_A_DO_CLEAR;
209  timerParam2.startTimer = true;
210  Timer_A_initUpMode(TA2_BASE, &timerParam2);
211  /* ---End configure TA2.1 for 1/sec to trigger the pulse generation and toggle LED--- */
212 
213  while(1)
214  {
215  // Enter LPM0 w/interrupt
216  __bis_SR_register(LPM0_bits | GIE);
217  // For debugger
218  __no_operation();
219  }
220 }
221 
222 // Timer A2 interrupt service routine
223 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
224 #pragma vector = TIMER2_A1_VECTOR
225 __interrupt void Timer2_A1_ISR(void)
226 #elif defined(__GNUC__)
227 void __attribute__ ((interrupt(TIMER2_A1_VECTOR))) Timer2_A1_ISR(void)
228 #else
229 #error Compiler not supported!
230 #endif
231 {
232  switch(__even_in_range(TA2IV, TAIV__TAIFG))
233  {
234  case TAIV__NONE: break; // No interrupt
235  case TAIV__TACCR1:
236  SDHS_endConversion(SDHS_BASE);
237  SDHS_startConversion(SDHS_BASE); // Start conversion
238  break;
239  case TAIV__TAIFG: break; // overflow
240  default: break;
241  }
242 }
243 
244 // SDHS interrupt service routine
245 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
246 #pragma vector = SDHS_VECTOR
247 __interrupt void SDHS_ISR(void)
248 #elif defined(__GNUC__)
249 void __attribute__ ((interrupt(SDHS_VECTOR))) SDHS_ISR(void)
250 #else
251 #error Compiler not supported!
252 #endif
253 {
254  switch(__even_in_range(SDHSIIDX, IIDX_6))
255  {
256  case IIDX_0: break; // No interrupt
257  case IIDX_1: break; // OVF interrupt
258  case IIDX_2: // ACQDONE interrupt
259  GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); // Toggle LED to show new cycle
260  __delay_cycles(10000);
261  __no_operation(); //put breakpoint here to view results
262  break;
263  case IIDX_3: break; // SSTRG interrupt
264  case IIDX_4: break; // DTRDY interrupt
265  case IIDX_5: break; // WINHI interrupt
266  case IIDX_6: break; // WINLO interrupt
267  default: break;
268  }
269 }
270 
271 // Timer A4 interrupt service routine
272 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
273 #pragma vector = TIMER4_A0_VECTOR
274 __interrupt void Timer4_A0_ISR(void)
275 #elif defined(__GNUC__)
276 void __attribute__ ((interrupt(TIMER4_A0_VECTOR))) Timer4_A0_ISR(void)
277 #else
278 #error Compiler not supported!
279 #endif
280 {
281  // Stop the timer and wake up from LPM
282  Timer_A_startCounter(TA4_BASE, TIMER_A_STOP_MODE);
283  __bic_SR_register_on_exit(LPM3_bits | GIE);
284  __no_operation();
285 }
volatile uint16_t results[Num_of_Results]
__no_operation()
__bic_SR_register_on_exit(LPM3_bits|GIE)
__delay_cycles(500000)
void main(void)